"""
安装程序脚本
用于在目标电脑上安装 LAN对讲机
"""
import os
import sys
import shutil
import winreg
from pathlib import Path
import tkinter as tk
from tkinter import ttk, messagebox, filedialog


class InstallerGUI:
    """安装程序图形界面"""
    
    def __init__(self):
        self.root = tk.Tk()
        self.root.title("LAN对讲机 - 安装程序")
        self.root.geometry("550x500")
        self.root.resizable(False, False)
        
        # 居中显示
        self.root.update_idletasks()
        screen_width = self.root.winfo_screenwidth()
        screen_height = self.root.winfo_screenheight()
        x = (screen_width - 550) // 2
        y = (screen_height - 500) // 2
        self.root.geometry(f"550x500+{x}+{y}")
        
        # 默认安装路径
        self.install_path = str(Path.home() / "AppData" / "Local" / "LAN对讲机")
        
        # 选项
        self.create_desktop_shortcut = tk.BooleanVar(value=True)
        self.auto_start = tk.BooleanVar(value=False)
        
        self.setup_ui()
        
    def setup_ui(self):
        """设置界面"""
        # 标题
        title_frame = tk.Frame(self.root, bg="#2196F3", height=80)
        title_frame.pack(fill=tk.X)
        title_frame.pack_propagate(False)
        
        title_label = tk.Label(
            title_frame,
            text="LAN对讲机 安装向导",
            font=("微软雅黑", 18, "bold"),
            bg="#2196F3",
            fg="white"
        )
        title_label.pack(expand=True)
        
        # 主内容区域
        content_frame = tk.Frame(self.root, padx=20, pady=20)
        content_frame.pack(fill=tk.BOTH, expand=True)
        
        # 欢迎信息
        welcome_label = tk.Label(
            content_frame,
            text="欢迎使用 LAN对讲机！\n\n这个向导将帮助您在计算机上安装程序。",
            font=("微软雅黑", 10),
            justify=tk.LEFT
        )
        welcome_label.pack(pady=(0, 20))
        
        # 安装路径选择
        path_frame = tk.LabelFrame(content_frame, text="安装位置", font=("微软雅黑", 9))
        path_frame.pack(fill=tk.X, pady=10)
        
        path_inner_frame = tk.Frame(path_frame, padx=10, pady=10)
        path_inner_frame.pack(fill=tk.X)
        
        self.path_entry = tk.Entry(path_inner_frame, font=("微软雅黑", 9))
        self.path_entry.insert(0, self.install_path)
        self.path_entry.pack(side=tk.LEFT, fill=tk.X, expand=True)
        
        browse_btn = tk.Button(
            path_inner_frame,
            text="浏览...",
            command=self.browse_path,
            font=("微软雅黑", 9)
        )
        browse_btn.pack(side=tk.LEFT, padx=(5, 0))
        
        # 选项
        options_frame = tk.LabelFrame(content_frame, text="安装选项", font=("微软雅黑", 9))
        options_frame.pack(fill=tk.X, pady=10)
        
        options_inner_frame = tk.Frame(options_frame, padx=10, pady=10)
        options_inner_frame.pack(fill=tk.X)
        
        desktop_check = tk.Checkbutton(
            options_inner_frame,
            text="创建桌面快捷方式",
            variable=self.create_desktop_shortcut,
            font=("微软雅黑", 9)
        )
        desktop_check.pack(anchor=tk.W)
        
        autostart_check = tk.Checkbutton(
            options_inner_frame,
            text="开机自动启动",
            variable=self.auto_start,
            font=("微软雅黑", 9)
        )
        autostart_check.pack(anchor=tk.W)
        
        # 添加一些垂直间距
        tk.Label(content_frame, text="", height=2).pack()
        
        # 底部按钮 - 使用固定位置确保可见
        button_frame = tk.Frame(self.root, bg="#e8e8e8", height=80)
        button_frame.pack(fill=tk.X, side=tk.BOTTOM)
        button_frame.pack_propagate(False)  # 防止frame收缩
        
        # 使用容器来居中按钮
        button_container = tk.Frame(button_frame, bg="#e8e8e8")
        button_container.place(relx=0.5, rely=0.5, anchor=tk.CENTER)
        
        # 取消按钮
        cancel_btn = tk.Button(
            button_container,
            text="取消",
            command=self.cancel_install,
            font=("微软雅黑", 10),
            width=12,
            height=2
        )
        cancel_btn.pack(side=tk.LEFT, padx=10)
        
        # 开始安装按钮
        install_btn = tk.Button(
            button_container,
            text="开始安装",
            command=self.start_install,
            font=("微软雅黑", 12, "bold"),
            width=12,
            height=2,
            relief=tk.RAISED,
            borderwidth=3
        )
        install_btn.pack(side=tk.LEFT, padx=10)
        
        # 尝试设置绿色
        try:
            install_btn.configure(bg="#4CAF50", fg="white", activebackground="#45a049")
        except:
            pass
        
    def browse_path(self):
        """浏览安装路径"""
        path = filedialog.askdirectory(initialdir=self.path_entry.get())
        if path:
            self.install_path = os.path.join(path, "LAN对讲机")
            self.path_entry.delete(0, tk.END)
            self.path_entry.insert(0, self.install_path)
    
    def cancel_install(self):
        """取消安装"""
        if messagebox.askyesno("确认", "确定要取消安装吗？"):
            self.root.quit()
            sys.exit(0)
    
    def start_install(self):
        """开始安装"""
        self.install_path = self.path_entry.get()
        
        # 创建进度窗口
        progress_window = tk.Toplevel(self.root)
        progress_window.title("安装中...")
        progress_window.geometry("400x150")
        progress_window.resizable(False, False)
        progress_window.transient(self.root)
        progress_window.grab_set()
        
        # 居中显示
        progress_window.update_idletasks()
        x = (progress_window.winfo_screenwidth() // 2) - (400 // 2)
        y = (progress_window.winfo_screenheight() // 2) - (150 // 2)
        progress_window.geometry(f"+{x}+{y}")
        
        status_label = tk.Label(
            progress_window,
            text="正在安装...",
            font=("微软雅黑", 10)
        )
        status_label.pack(pady=20)
        
        progress_bar = ttk.Progressbar(
            progress_window,
            mode='indeterminate',
            length=300
        )
        progress_bar.pack(pady=10)
        progress_bar.start()
        
        # 执行安装
        try:
            self.perform_install(status_label)
            progress_bar.stop()
            progress_window.destroy()
            
            messagebox.showinfo("完成", "安装成功！")
            self.root.quit()
            
        except Exception as e:
            progress_bar.stop()
            progress_window.destroy()
            messagebox.showerror("错误", f"安装失败：{str(e)}")
    
    def perform_install(self, status_label=None):
        """执行安装过程"""
        def update_status(text):
            if status_label:
                status_label.config(text=text)
                status_label.update()
        
        # 1. 创建安装目录
        update_status("创建安装目录...")
        os.makedirs(self.install_path, exist_ok=True)
        
        # 2. 复制主程序
        update_status("复制程序文件...")
        exe_name = "LAN对讲机.exe"
        
        # 获取打包后的exe路径（当前运行的程序所在目录）
        if getattr(sys, 'frozen', False):
            # 打包后
            current_dir = os.path.dirname(sys.executable)
        else:
            # 开发环境
            current_dir = os.path.dirname(os.path.abspath(__file__))
        
        source_exe = os.path.join(current_dir, exe_name)
        target_exe = os.path.join(self.install_path, exe_name)
        
        if os.path.exists(source_exe):
            shutil.copy2(source_exe, target_exe)
        else:
            raise FileNotFoundError(f"找不到程序文件：{exe_name}")
        
        # 复制图标
        icon_name = "icon.ico"
        source_icon = os.path.join(current_dir, icon_name)
        target_icon = os.path.join(self.install_path, icon_name)
        if os.path.exists(source_icon):
            shutil.copy2(source_icon, target_icon)
        
        # 3. 创建快捷方式
        if self.create_desktop_shortcut.get():
            update_status("创建桌面快捷方式...")
            self.create_shortcut(target_exe, "Desktop")
        
        # 创建开始菜单快捷方式
        update_status("创建开始菜单快捷方式...")
        self.create_shortcut(target_exe, "StartMenu")
        
        # 4. 设置开机自启动
        if self.auto_start.get():
            update_status("配置开机自启动...")
            self.set_autostart(target_exe)
        
        # 5. 写入注册表（卸载信息）
        update_status("写入注册表...")
        self.write_uninstall_info(target_exe)
        
        update_status("安装完成！")
    
    def create_shortcut(self, target_path, location):
        """创建快捷方式"""
        try:
            import win32com.client
            
            shell = win32com.client.Dispatch("WScript.Shell")
            
            if location == "Desktop":
                shortcut_path = os.path.join(
                    os.path.expanduser("~"),
                    "Desktop",
                    "LAN对讲机.lnk"
                )
            else:  # StartMenu
                start_menu = os.path.join(
                    os.environ["APPDATA"],
                    "Microsoft\\Windows\\Start Menu\\Programs"
                )
                shortcut_path = os.path.join(start_menu, "LAN对讲机.lnk")
            
            shortcut = shell.CreateShortCut(shortcut_path)
            shortcut.Targetpath = target_path
            shortcut.WorkingDirectory = os.path.dirname(target_path)
            
            # 设置图标
            icon_path = os.path.join(os.path.dirname(target_path), "icon.ico")
            if os.path.exists(icon_path):
                shortcut.IconLocation = icon_path
            
            shortcut.save()
        except ImportError:
            # 如果没有 pywin32，使用备用方法
            pass
        except Exception as e:
            print(f"创建快捷方式失败: {e}")
    
    def set_autostart(self, exe_path):
        """设置开机自启动"""
        try:
            key = winreg.OpenKey(
                winreg.HKEY_CURRENT_USER,
                r"Software\Microsoft\Windows\CurrentVersion\Run",
                0,
                winreg.KEY_SET_VALUE
            )
            winreg.SetValueEx(key, "LAN对讲机", 0, winreg.REG_SZ, f'"{exe_path}"')
            winreg.CloseKey(key)
        except Exception as e:
            print(f"设置自启动失败: {e}")
    
    def write_uninstall_info(self, exe_path):
        """写入卸载信息到注册表"""
        try:
            key = winreg.CreateKey(
                winreg.HKEY_CURRENT_USER,
                r"Software\Microsoft\Windows\CurrentVersion\Uninstall\LAN对讲机"
            )
            
            winreg.SetValueEx(key, "DisplayName", 0, winreg.REG_SZ, "LAN对讲机")
            winreg.SetValueEx(key, "DisplayVersion", 0, winreg.REG_SZ, "2.1")
            winreg.SetValueEx(key, "Publisher", 0, winreg.REG_SZ, "WalkieTalkie")
            winreg.SetValueEx(key, "InstallLocation", 0, winreg.REG_SZ, self.install_path)
            winreg.SetValueEx(key, "DisplayIcon", 0, winreg.REG_SZ, exe_path)
            
            # 卸载命令（简单地提示手动删除）
            uninstall_cmd = f'cmd /c "echo 请手动删除文件夹：{self.install_path} && pause"'
            winreg.SetValueEx(key, "UninstallString", 0, winreg.REG_SZ, uninstall_cmd)
            
            winreg.CloseKey(key)
        except Exception as e:
            print(f"写入注册表失败: {e}")
    
    def run(self):
        """运行安装程序"""
        self.root.mainloop()


if __name__ == "__main__":
    app = InstallerGUI()
    app.run()


